package com.my.simple.common.handler;

import com.my.simple.common.exception.NoAccountAuthenticationException;
import com.my.simple.common.exception.NoLoginAuthenticationException;
import com.my.simple.common.exception.NoPermissionAuthenticationException;
import com.my.simple.web.vo.ResponseData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@RestControllerAdvice
public class MyExceptionHandler {
    private static final Logger LOG = LoggerFactory.getLogger(MyExceptionHandler.class);

    @ExceptionHandler(ArithmeticException.class)
    public ResponseEntity<ResponseData> zeroError(ArithmeticException ex) {
        String errorInfo = "divide zero";
        LOG.error(errorInfo, ex);
        ResponseData responseData = new ResponseData();
        responseData.setMessage(errorInfo);
        ResponseEntity<ResponseData> responseEntity = new ResponseEntity<ResponseData>(responseData, HttpStatus.INTERNAL_SERVER_ERROR);
        return responseEntity;
    }

    @ExceptionHandler(NoAccountAuthenticationException.class)
    public ResponseEntity<ResponseData> error(NoAccountAuthenticationException ex) {
        String errorInfo = "user account is not exists";
        LOG.error(errorInfo, ex);
        ResponseData responseData = new ResponseData();
        responseData.setMessage(errorInfo);
        ResponseEntity<ResponseData> responseEntity = new ResponseEntity<ResponseData>(responseData, HttpStatus.BAD_REQUEST);
        return responseEntity;
    }

    @ExceptionHandler(NoLoginAuthenticationException.class)
    public ResponseEntity<ResponseData> error(NoLoginAuthenticationException ex) {
        String errorInfo = "no login";
        LOG.error(errorInfo, ex);
        ResponseData responseData = new ResponseData();
        responseData.setMessage(errorInfo);
        ResponseEntity<ResponseData> responseEntity = new ResponseEntity<ResponseData>(responseData, HttpStatus.UNAUTHORIZED);
        return responseEntity;
    }

    @ExceptionHandler(NoPermissionAuthenticationException.class)
    public ResponseEntity<ResponseData> error(NoPermissionAuthenticationException ex) {
        String errorInfo = "no permission";
        LOG.error(errorInfo, ex);
        ResponseData responseData = new ResponseData();
        responseData.setMessage(errorInfo);
        ResponseEntity<ResponseData> responseEntity = new ResponseEntity<ResponseData>(responseData, HttpStatus.FORBIDDEN);
        return responseEntity;
    }

    @ExceptionHandler(BindException.class)
    public ResponseEntity<ResponseData> error(BindException ex) {
        String errorInfo = "call api argument is illegal";
        LOG.error(errorInfo, ex);
        BindingResult bindResult = ex.getBindingResult();
        Map<String, String> map = new ConcurrentHashMap<>();

        if (ex.hasErrors()) {
            List<FieldError> fieldErrorList = bindResult.getFieldErrors();
            for (FieldError fieldError : fieldErrorList) {
                map.put(fieldError.getField(), fieldError.getDefaultMessage());
                LOG.debug("[{}.{}]{}", fieldError.getObjectName(), fieldError.getField(), fieldError.getDefaultMessage());
            }
        }

        ResponseData responseData = new ResponseData();
        responseData.setMessage(errorInfo);
        responseData.setData(map);
        ResponseEntity<ResponseData> responseEntity = new ResponseEntity<ResponseData>(responseData, HttpStatus.BAD_REQUEST);
        return responseEntity;
    }

    @ExceptionHandler(IllegalArgumentException.class)
    public ResponseEntity<ResponseData> error(IllegalArgumentException ex) {
        String errorInfo = "argument is illegal";
        LOG.error(errorInfo, ex);
        ResponseData responseData = new ResponseData();
        responseData.setMessage(errorInfo);
        ResponseEntity<ResponseData> responseEntity = new ResponseEntity<ResponseData>(responseData, HttpStatus.BAD_REQUEST);
        return responseEntity;
    }

    @ExceptionHandler(HttpMessageNotReadableException.class)
    public ResponseEntity<ResponseData> error(HttpMessageNotReadableException ex) {
        String errorInfo = "request parameters is error, please check";
        LOG.error(errorInfo, ex);
        ResponseData responseData = new ResponseData();
        responseData.setMessage(errorInfo);
        ResponseEntity<ResponseData> responseEntity = new ResponseEntity<ResponseData>(responseData, HttpStatus.BAD_REQUEST);
        return responseEntity;
    }

    @ExceptionHandler(Exception.class)
    public ResponseEntity<ResponseData> error(Exception ex) {
        String errorInfo = "server error, please contract to web administrator";
        LOG.error(errorInfo, ex);
        ResponseData responseData = new ResponseData();
        responseData.setMessage(errorInfo);
        ResponseEntity<ResponseData> responseEntity = new ResponseEntity<ResponseData>(responseData, HttpStatus.INTERNAL_SERVER_ERROR);
        return responseEntity;
    }

}
